#define __NOLIBBASE__
#define USE_INLINE_STDARG

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/multimedia.h>
#include <exec/memory.h>
#include <classes/multimedia/sound.h>
#include <clib/alib_protos.h>



extern struct Library *SysBase, *DOSBase;
struct Library *IntuitionBase, *MultimediaBase, *PictureOutputBase;
CONST_STRPTR Template = "FILE/A";


BOOL init_resources(VOID)
{
	if (!(IntuitionBase = OpenLibrary("intuition.library", 50))) return FALSE;
	if (!(MultimediaBase = OpenLibrary("multimedia/multimedia.class", 52))) return FALSE;
	if (!(PictureOutputBase = OpenLibrary("multimedia/picture.output", 51))) return FALSE;
	return TRUE;
}



VOID free_resources(VOID)
{
	if (PictureOutputBase) CloseLibrary(PictureOutputBase);
	if (MultimediaBase) CloseLibrary(MultimediaBase);
	if (IntuitionBase) CloseLibrary(IntuitionBase);
}



STRPTR read_args(VOID)
{
	struct RDArgs *args;
	LONG params[1];
	STRPTR filename = NULL;

	if (args = ReadArgs(Template, params, NULL))
	{
		if (filename = AllocVecTaskPooled(strlen((STRPTR)params[0]) + 1))
		{
			strcpy(filename, (STRPTR)params[0]);
		}

		FreeArgs(args);
	}

	return filename;
}



VOID play_sound(STRPTR filename)
{
	Object *source, *player;
	struct MsgPort *port;
	struct Message *msg;


	if (port = CreateMsgPort())
	{
		if (msg = AllocVec(sizeof(struct Message), MEMF_PUBLIC | MEMF_CLEAR))
		{
			msg->mn_Node.ln_Type = NT_MESSAGE;
			msg->mn_ReplyPort = port;
			msg->mn_Length = sizeof(struct Message);

			if (source = MediaNewObjectTags(
				MMA_StreamName, (LONG)"Work:Pictures/Lakas1/IMGP0939.jpg",
				MMA_StreamType, (LONG)"file.stream",
				MMA_MediaType, MMT_PICTURE,
			TAG_END))
			{
				Printf("Debug_5\n");
				if (player = NewObject(NULL, "picture.output", TAG_END))
				{
					Printf("Debug_6\n");
					if (MediaConnectTagList(source, 0, player, 0, NULL))
					{
						ULONG signals, sigmask = 1 << port->mp_SigBit;
						Printf("Debug_7\n");

						/*-----------------------------------------------------------*/
						/* I want to wait both for message reply (end of sound) and  */
						/* CTRL-C signal (user break). That is why I calculate       */
						/* signal mask and use Wait() instead of WaitPort().         */
						/*-----------------------------------------------------------*/

//						DoMethod(player, MMM_Sound_ReplyMsgAtEnd, (LONG)msg);
						DoMethod(player, MMM_Pull);
						Printf("Debug_8\n");
						signals = Wait(SIGBREAKF_CTRL_C | sigmask);

						if (signals & SIGBREAKF_CTRL_C) PutStr("User break!\n");

						if (signals & sigmask)
						{
							GetMsg(port);                // empty port queue
							PutStr("End of sound.\n");
						}
					}

					DisposeObject(player);
				}

				DisposeObject(source);
			}
			else Printf("Reggae was unable to decode \"%s\".\n", (LONG)filename);

			FreeVec(msg);
		}

		DeleteMsgPort(port);
	}

}



int main(void)
{
	int result = RETURN_OK;
	STRPTR filename;

	Printf("Debug_0\n");
	
	if (init_resources())
	{
		Printf("Debug_1\n");
		if (filename = read_args())
		{
			Printf("Debug_2\n");
			play_sound(filename);
			FreeVecTaskPooled(filename);
		}
		else {
		result = RETURN_ERROR;
		Printf("Debug_3\n");
		}
	}
	else {
		Printf("Debug_4\n");
		result = RETURN_FAIL;
	}

	free_resources();

	return result;
}
